home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------------*\
- | rleapp.c - RLE Sample Application. Multimedia Systems Group |
- | |
- \*----------------------------------------------------------------------------*/
-
- /*
- (C) Copyright Microsoft Corp. 1991, 1992. All rights reserved.
-
- You have a royalty-free right to use, modify, reproduce and
- distribute the Sample Files (and/or any modified version) in
- any way you find useful, provided that you agree that
- Microsoft has no warranty obligations or liability for any
- Sample Application Files which are modified.
-
- If you did not get this from Microsoft Sources, then it may not be the
- most current version. This sample code in particular will be updated
- and include more documentation.
-
- Sources are:
- The MM Sys BBS: The phone number is 206 936-4082.
- CompuServe: WINSDK forum, MDK section.
- */
-
- #include <windows.h>
- #include <mmsystem.h>
- #include <commdlg.h>
-
- #include "gmem.h"
- #include "rleapp.h"
- #include "rle.h"
- #include "dib.h"
-
- //
- // DisplayDib API
- //
- #define DISPLAYDIB_MODE 0x000F
- #define DISPLAYDIB_NOPALETTE 0x0010
- #define DISPLAYDIB_NOCENTER 0x0020
- #define DISPLAYDIB_BEGIN 0x8000
- #define DISPLAYDIB_END 0x4000
- #define DISPLAYDIB_MODE_DEFAULT 0x0000
- #define DISPLAYDIB_MODE_320x200x8 0x0001
- #define DISPLAYDIB_MODE_320x400x8 0x0002
- #define DISPLAYDIB_MODE_360x480x8 0x0003
- #define DISPLAYDIB_MODE_320x480x8 0x0004
- #define DISPLAYDIB_MODE_320x240x8 0x0005
-
- WORD (FAR PASCAL *DisplayDib)(LPBITMAPINFOHEADER lpbi, LPSTR lpBits, WORD wFlags);
-
- char szDisplayDibDll[] = "DISPDIB.DLL";
- HANDLE hDisplayDibDll;
-
- /*----------------------------------------------------------------------------*\
- | |
- | g l o b a l v a r i a b l e s |
- | |
- \*----------------------------------------------------------------------------*/
-
- HANDLE hAccTable; /* handle to accelerator table */
-
- static char szAppName[]="RLE";
- static char gszCurFilespec[128]; /* used for File Revert */
- static HANDLE hInstApp;
- static HWND hwndApp;
- static int tmHeight;
-
- int gChannels; // Info about the Wave data
- DWORD gSamplesPerSec;
- DWORD gdwBufferLength = 0L; // start and len of movie's 1st wave
- BYTE huge * glpData = NULL;
- LPWAVEFORMAT pWaveFormat;
- LPWAVEHDR pwhMovie;
- HWAVEOUT hWaveOut;
-
- char szFilters[] = "Rle Files\0*.rle;*.rl0\0"
- "Bitmaps\0*.bmp;*.dib\0"
- "Wave Files\0*.wav\0"
- "All Files\0*.*\0"
- "";
-
- FRAME far *arFrames;
- int curFrame;
- int curWave;
- int numFrames;
- int totFrames = 0;
- int numWaves; // how many frames have wave data
- int lastWave; // the first frame without wave data (zero based)
- HPALETTE hpalApp;
- POINT ptFrame = {0,0};
- POINT ptSizeFrame = {0,0};
- BOOL fDirty;
-
- WORD gDisplayMode = 0;
- BOOL fPlay = FALSE;
- BOOL fActive = FALSE;
- BOOL fLoading = FALSE;
- BOOL fStatus = TRUE;
- BOOL fPaint = TRUE;
-
- BOOL fFullPaint = FALSE;
- BOOL fSkipFrames = FALSE;
-
- WORD wPalFlags = 0; // PC_NOCOLLAPSE;
-
- long RealFramesSec;
- long FramesSec = (15 * FramesSecScale);
-
- LONG msFrameBase = 0L;
- int nFramesPlayed = 0;
-
- OPENFILENAME ofn;
-
- /*----------------------------------------------------------------------------*\
- | |
- | f u n c t i o n d e f i n i t i o n s |
- | |
- \*----------------------------------------------------------------------------*/
-
- LONG EXPORT AppWndProc (HWND hwnd, unsigned uiMessage, WORD wParam, LONG lParam);
-
- HPALETTE CopyPalette(HPALETTE hpal);
- BOOL QueryClose(HWND hwnd);
-
- void PlayFrame(HDC hdc, int iFrame, int x, int y, BOOL fIgnoreFlags);
- void PaintStatus(HWND hwnd, HDC hdc);
-
- void RleFrames(void);
- void RleAllFrames(HWND hwnd);
- BOOL RealizeFrames(void);
-
- LONG NEAR PASCAL AppCommand(HWND hwnd, unsigned msg, WORD wParam, LONG lParam);
- void NEAR PASCAL AppPaint(HWND hwnd, HDC hdc);
-
- /*----------------------------------------------------------------------------*\
- \*----------------------------------------------------------------------------*/
-
- HCURSOR hcurSave;
- int fWait = 0;
-
- void StartWait()
- {
- if (fWait++ == 0)
- {
- SetCursor(LoadCursor(NULL,IDC_WAIT));
- }
- }
-
- void EndWait()
- {
- if (--fWait == 0)
- {
- SetCursor(LoadCursor(NULL,IDC_ARROW));
- InvalidateRect(hwndApp, NULL, TRUE);
- }
- }
-
- BOOL WinYield()
- {
- MSG msg;
- BOOL fAbort=FALSE;
-
- while(fWait > 0 && PeekMessage(&msg,NULL,0,0,PM_REMOVE))
- {
- if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE)
- fAbort = TRUE;
- if (msg.message == WM_SYSCOMMAND && (msg.wParam & 0xFFF0) == SC_CLOSE)
- fAbort = TRUE;
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return fAbort;
- }
-
- void SoundPlay(int iFrame, int iCount)
- {
- LPWAVEHDR pwh;
- DWORD dwFirstSample, dwLenSegment;
-
- if (hWaveOut && pwhMovie)
- {
- pwh = pwhMovie;
-
- if (!(pwh->dwFlags & WHDR_DONE))
- {
- waveOutReset(hWaveOut);
- pwh->dwFlags &= ~WHDR_DONE;
- }
-
- dwFirstSample = muldiv32(iFrame,FramesSecScale*gSamplesPerSec*gChannels,FramesSec);
- dwLenSegment = muldiv32(iCount,FramesSecScale*gSamplesPerSec*gChannels,FramesSec);
-
- if (dwLenSegment > (gdwBufferLength - dwFirstSample))
- dwLenSegment = gdwBufferLength - dwFirstSample;
-
- if (dwFirstSample < gdwBufferLength)
- {
- (BYTE huge *)(pwh->lpData) = (BYTE huge *)glpData + dwFirstSample;
- pwh->dwBufferLength = dwLenSegment;
- }
-
- if (dwLenSegment > 0)
- {
- waveOutWrite(hWaveOut,pwh, sizeof(WAVEHDR));
- }
- }
- }
-
- void SoundOpen()
- {
- WORD err;
- char ach[80];
-
- if (!hWaveOut && pWaveFormat && pwhMovie)
- {
- err = waveOutOpen(&hWaveOut, WAVE_MAPPER, pWaveFormat, hwndApp, 0, CALLBACK_WINDOW);
-
- if (err)
- {
- if (waveOutGetNumDevs() > 0)
- {
- waveOutGetErrorText(err, ach, sizeof(ach));
- ErrMsg("Unable to open wave device!\n%ls", (LPSTR)ach);
- }
- hWaveOut = NULL;
- return;
- }
-
- pwhMovie->dwBufferLength=gdwBufferLength;
- pwhMovie->lpData = glpData;
-
- waveOutPrepareHeader(hWaveOut,pwhMovie,sizeof(WAVEHDR));
- }
- }
-
- void SoundClose()
- {
- if (hWaveOut)
- {
- pwhMovie->dwBufferLength=gdwBufferLength;
- pwhMovie->lpData = glpData;
-
- waveOutReset(hWaveOut);
- waveOutUnprepareHeader(hWaveOut,pwhMovie,sizeof(WAVEHDR));
-
- waveOutClose(hWaveOut);
- hWaveOut = NULL;
- }
- }
-
- /*----------------------------------------------------------------------------*\
- | |
- \*----------------------------------------------------------------------------*/
- #define FRAME_NEXT -1
- #define FRAME_PREV -2
- void ShowFrame(int nFrame)
- {
- HDC hdc;
-
- if (numFrames == 0)
- {
- InvalidateRect(hwndApp,NULL,TRUE);
- return;
- }
-
- switch (nFrame)
- {
- case FRAME_NEXT:
- curFrame = (curFrame+1) % numFrames;
- break;
-
- case FRAME_PREV:
- if (curFrame-- == 0)
- curFrame = numFrames-1;
- break;
-
- default:
- curFrame = nFrame % numFrames;
- InvalidateRect(hwndApp,NULL,FALSE);
- UpdateWindow(hwndApp);
- return;
- }
-
- hdc = GetDC(hwndApp);
-
- PaintStatus(hwndApp,hdc);
- PlayFrame(hdc, curFrame, ptFrame.x, ptFrame.y, FALSE);
-
- ReleaseDC(hwndApp,hdc);
- }
-
- void FreeFrame(int iFrame)
- {
- if (iFrame < 0 || iFrame >= numFrames)
- return;
-
- if (arFrames[iFrame].hpal && !(arFrames[iFrame].f & F_PALSHARED))
- DeleteObject(arFrames[iFrame].hpal);
- if (arFrames[iFrame].hdib)
- GFree(arFrames[iFrame].hdib);
- if (arFrames[iFrame].hrle && arFrames[iFrame].hdib != arFrames[iFrame].hrle)
- GFree(arFrames[iFrame].hrle);
-
- arFrames[iFrame].hdib = NULL;
- arFrames[iFrame].hrle = NULL;
- arFrames[iFrame].hpal = NULL;
- arFrames[iFrame].f = 0;
- }
-
- void FreeFrames()
- {
- int i;
-
- SoundClose();
-
- for (i=0; i<numFrames; i++)
- FreeFrame(i);
-
- numFrames = 0;
- curFrame = 0;
- numWaves = 0;
- lastWave = 0;
- curWave = 0;
- fPaint = TRUE;
- fDirty = FALSE;
-
- if (pWaveFormat) // Free the movie's wave header
- GFreePtr(pWaveFormat);
-
- if (pwhMovie) // Free the movie's wave data
- GFreePtr(pwhMovie);
-
- pWaveFormat = NULL;
- pwhMovie = NULL;
-
- ShowFrame(0);
- }
-
- /* This routine will play the movie in full screen VGA mode using DISPDIB */
-
- void PlayVga(HWND hwnd)
- {
- MSG msg;
- HANDLE hdib;
- HPALETTE hpal;
- WORD f;
- long msTime;
- int iFrame;
-
- if (numFrames == 0)
- return;
-
- curFrame = 0;
- hdib = FrameRle(curFrame);
- hpal = FramePalette(curFrame);
- f = FrameFlags(curFrame);
- // We must use RGB colours so the right palette is used
-
- SetDibUsage(hdib, hpal, DIB_RGB_COLORS);
- DisplayDib(GLock(hdib), NULL, DISPLAYDIB_BEGIN | gDisplayMode);
- DisplayDib(GLock(hdib), NULL, NULL);
- SetDibUsage(hdib, hpal, DIB_PAL_COLORS);
-
- SetTimer(hwnd,1,2000,NULL); // Wait 2 seconds so VGA can sync
- GetMessage(&msg, NULL, WM_TIMER, WM_TIMER);
- KillTimer(hwnd,1);
-
- GetAsyncKeyState(VK_ESCAPE); // If ESC was hit, use it up now
-
- SoundOpen();
- SoundPlay(0, numFrames);
- msFrameBase = timeGetTime();
-
- while (GetAsyncKeyState(VK_ESCAPE) == 0)
- {
- if(PeekMessage(&msg,hwnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOYIELD | PM_REMOVE))
- break;
-
- //
- // wait until it is time for next frame.
- //
- do
- {
- msTime = timeGetTime() - msFrameBase;
- iFrame = (int)(msTime * FramesSec / 1000 / FramesSecScale);
- } while (iFrame == curFrame);
-
- if (fSkipFrames)
- curFrame = iFrame;
- else
- curFrame++;
-
- if (curFrame >= numFrames)
- {
- curFrame = 0;
- SoundPlay(0, numFrames);
- msFrameBase = timeGetTime();
- }
-
- hdib = FrameRle(curFrame);
- hpal = FramePalette(curFrame);
- f = FrameFlags(curFrame);
-
-
- // New palette for this frame, so use RGB colours
-
- if (!(f & F_PALSHARED)) // palette changed?
- {
- SetDibUsage(hdib, hpal, DIB_RGB_COLORS);
- DisplayDib(GLock(hdib), NULL, NULL);
- SetDibUsage(hdib, hpal, DIB_PAL_COLORS);
- }
- else // same palette as last time, use PAL colours
- {
- DisplayDib(GLock(hdib), NULL, DISPLAYDIB_NOPALETTE);
- }
- }
-
- DisplayDib(NULL, NULL, DISPLAYDIB_END);
- SoundClose();
- }
-
-
- HANDLE RenderFrame(int iFrame)
- {
- HANDLE hdib;
- int i;
-
- if (iFrame<0 || iFrame>=numFrames)
- return NULL;
-
- //
- // if we have a DIB for this frame, return it!
- //
- if (arFrames[iFrame].hdib)
- return arFrames[iFrame].hdib;
-
- StartWait();
-
- //
- // Search for the 'nearest' full frame (or the first frame)
- //
- for (i=iFrame; i>0 && arFrames[i].hdib==NULL; i--)
- ;
-
- //
- // Create a DIB of the last full frame found
- //
- if (arFrames[i].hdib == NULL)
- {
- LPBITMAPINFOHEADER prle;
- LPBITMAPINFOHEADER pdib;
-
- prle = GLock(arFrames[i].hrle);
- hdib = CreateDib(8, (int)prle->biWidth, (int)prle->biHeight);
- if (!hdib)
- {
- ErrMsg("Out of Memory Error");
- goto exit;
- }
-
- pdib = GLock(hdib);
-
- //
- // copy over the color table from the RLE to the empty DIB
- //
- MemCopy((LPSTR)pdib+(int)pdib->biSize,
- (LPSTR)prle+(int)prle->biSize, 256*sizeof(RGBQUAD));
-
- }
- else
- {
- hdib = CopyDib(arFrames[i].hdib);
- i++;
- }
-
- if (!hdib)
- {
- ErrMsg("Out of Memory Error");
- goto exit;
- }
-
- //
- // Create the frame from 'scratch' (by playing each frame from zero)
- //
- for (; i<=iFrame; i++)
- PlayRleDib(hdib, 0, 0, arFrames[i].hrle);
-
- arFrames[iFrame].hdib = hdib;
-
- exit:
- EndWait();
- return hdib;
- }
-
- void NukeRle(int i) // Erase the RLE if a DIB exists
- {
- if ((i < 0) || (i >= numFrames))
- return;
- if (arFrames[i].hdib && arFrames[i].hrle &&
- arFrames[i].hdib != arFrames[i].hrle)
- {
- GFree(arFrames[i].hrle);
- arFrames[i].hrle = NULL;
- arFrames[i].f &= ~(F_RLE);
- }
- }
-
- void NukeDib(int i) // Erase the DIB if an RLE exists
- {
- if ((i < 0) || (i >= numFrames))
- return;
- if (arFrames[i].hdib && arFrames[i].hrle &&
- arFrames[i].hdib != arFrames[i].hrle)
- {
- GFree(arFrames[i].hdib);
- arFrames[i].hdib = NULL;
- }
- }
-
- /* RleFrame - Rle the given frame - and maybe update the DIB copy, too
- ======== */
-
- HANDLE RleFrame(int i, BOOL fUpdateDib)
- {
- HPALETTE hpal;
- HANDLE hrle;
- HANDLE hdib, hdibT;
-
- if (i < 0 || i >= numFrames)
- return NULL;
-
- hrle = arFrames[i].hrle;
-
- if (hrle) /* Return the one we've got already */
- return hrle;
-
- hpal = arFrames[i].hpal;
-
- if (i == 0)
- {
- if (arFrames[i].hdib)
- {
- fDirty = TRUE;
- arFrames[i].hrle = RleDeltaFrame(NULL,NULL,arFrames[i].hdib,0,0,0);
-
- if (!arFrames[i].hrle)
- ErrMsg("Out of Memory Error");
- else
- arFrames[i].f |= F_RLE;
- }
- return arFrames[i].hrle;
- }
- else
- {
- if (arFrames[i].hdib)
- {
- fDirty = TRUE;
-
- // We need a DIB of the previous frame in order to Delta-RLE this frame
-
- hdib = arFrames[i-1].hdib;
- hdibT = RenderFrame(i-1); /* Un-RLE's the previous frame */
- if (!hdibT)
- {
- ErrMsg("Out of Memory Error");
- return NULL;
- }
- arFrames[i].hrle = RleDeltaFrame(NULL,arFrames[i-1].hdib,
- arFrames[i].hdib,0,0,0);
-
- if (!arFrames[i].hrle)
- ErrMsg("Out of Memory Error");
- else
- arFrames[i].f |= F_RLE;
- }
- }
-
- // Now, change the DIB copy to reflect what will actually be on the screen
- // at this point in the movie, since the RLE may have lost some detail.
-
- if (fUpdateDib && arFrames[i].hrle)
- {
- NukeDib(i);
- RenderFrame(i);
- }
- ShowFrame(i);
-
- return arFrames[i].hrle;
- }
-
- void PurgeFrames()
- {
- int i;
-
- //
- // Delete all HDIBs we don't need to save memory
- //
- for (i=0; i<numFrames; i++)
- NukeDib(i);
- }
-
- BOOL RealizeFrames()
- {
- int i;
- int curSave = curFrame;
-
- StartWait();
- for (i = 0; i < numFrames; i++)
- {
- if (!arFrames[i].hdib)
- if (!RenderFrame(i))
- goto realizebarf;
-
- NukeRle(i);
- fDirty = TRUE;
- ShowFrame(i);
- if (WinYield())
- goto realizebarf;
- }
- EndWait();
- ShowFrame(curSave);
- return TRUE;
-
- realizebarf:
- EndWait();
- ShowFrame(curSave);
- return FALSE;
- }
-
- //
- // Make all of the frames have a palette that is an identity mapping to the
- // "real" palette.
- //
- void MapIdentFrames()
- {
- int i;
- int curSave = curFrame;
- HANDLE hdib;
- HPALETTE hpalFrame=NULL;
- HPALETTE hpal;
- HDC hdc;
- HWND hwndT;
-
- StartWait();
- for (i=0; i<numFrames; i++)
- {
- ShowFrame(i);
-
- hdib = FrameRle(i);
-
- // For each palette change, we must give our window the focus and
- // do the mapping, and give focus back again
-
- if (!(FrameFlags(i) & F_PALSHARED))
- {
- hwndT = GetActiveWindow(); // who is the active window?
- SetActiveWindow(hwndApp); // make it us.
-
- if (hpalFrame)
- DeleteObject(hpalFrame);
-
- hpalFrame = FramePalette(i);
-
- hdc = GetDC(hwndApp);
- SelectPalette(hdc, hpalFrame, FALSE);
- RealizePalette(hdc);
- ReleaseDC(hwndApp,hdc);
-
- hpal = CreateSystemPalette();
-
-
- SetActiveWindow(hwndT); // Put the old window back in focus
- }
-
- SetDibUsage(hdib,hpalFrame,DIB_RGB_COLORS);
-
- MapDib(hdib, hpal);
- FramePalette(i) = hpal;
-
- SetDibUsage(hdib,hpal,DIB_PAL_COLORS);
-
- if (WinYield())
- break;
- }
- EndWait();
-
- if (hpalFrame)
- DeleteObject(hpalFrame);
-
- ShowFrame(curSave);
- }
-
- //
- // make all frames relative to a given palette
- //
- void MapPalFrames(HPALETTE hpalMap)
- {
- int i;
- HANDLE hdib;
- HPALETTE hpal;
- StartWait();
- for (i=0; i<numFrames; i++)
- {
- ShowFrame(i);
-
- hdib = FrameRle(i);
- hpal = FramePalette(i);
-
- SetDibUsage(hdib,hpal,DIB_RGB_COLORS);
- MapDib(hdib, hpalMap);
- SetDibUsage(hdib,hpalMap,DIB_PAL_COLORS);
-
- if (WinYield())
- break;
- }
-
- for (i=0; i<numFrames; i++)
- {
- if (!(arFrames[i].f & F_PALSHARED))
- DeleteObject(arFrames[i].hpal);
-
- arFrames[i].f |= F_PALSHARED;
- arFrames[i].hpal = hpalMap;
- }
- arFrames[0].f &= ~F_PALSHARED;
-
- EndWait();
- ShowFrame(0);
- }
-
-
- /* This routine will make RLE copies of all of the frames, instead of DIB
- copies (RLEs are usually much smaller). It then erases the DIB copies.
- However, we don't want to keep 2 bitmaps for each frame until the end
- of this routine, and then erase the DIB copy because that wastes memory.
- BUT: We don't want to erase each DIB copy as an RLE copy is made, either,
- because that makes this routine take HOURS to run. Why, you ask? Because
- in order to RLE a frame, you need DIB copies of that frame and the one
- before it, so you must make a DIB copy of both of those frames. If you
- don't have any DIBs in your movie, you will have to start at frame one
- and play the movie up to the current frame to get those DIBs. Plus, you
- will have to do this for EVERY FRAME in the movie as this code runs.
- For the last frames of a very long movie, this will take many minutes,
- and the routine will start running slower and slower as it gets further
- and further into the movie.
-
- The solution is to make a note of each frame that had a DIB and was
- RLE'd. Then, the next time a frame is RLE'd, it will only have to go
- back to the last frame and play forward from that spot to get the DIBs that
- it needs to RLE the frame. It won't need to go back to the beginning of
- the movie. Then the DIB copy of the previous frame is erased, but the
- one of the current frame is kept and remembered. Thus, there will always
- be one frame in the movie earlier than the current frame that has a DIB
- copy, and you will never have to go back and play all the frames from
- the beginning of the movie.
- */
-
-
- void RleAllFrames(HWND hwnd)
- {
- int curSave = curFrame;
- HPALETTE hpal = NULL;
- int i;
- HANDLE hrle, hrleT;
- int wLastRle = -1; // Last frame that was RLE-d
-
- {
- fDirty=TRUE;
-
- StartWait();
-
- for (i = 0; i < numFrames; i++)
- {
- hrleT = arFrames[i].hrle; // Remember the HRLE of this frame
- if ((hrle = RleFrame(i, TRUE)) == NULL) /* RLE that frame */
- goto barf; // something went wrong
-
- ShowFrame(i);
- if (WinYield())
- goto barf;
-
- if (hrle != hrleT)
- { // This frame was just RLE'd.
- NukeDib(wLastRle); // Erase the DIB of the last frame.
- wLastRle = i; // Mark this frame as the next one
- // to be deleted.
- }
- }
-
- barf:
- PurgeFrames(); /* Delete the DIB copy of frames that are RLE'd */
-
- EndWait();
- ShowFrame(curSave);
- }
- }
-
- void PlayFrame(HDC hdc, int iFrame, int x, int y, BOOL fIgnoreFlags)
- {
- HPALETTE hpal,hpalT;
- HANDLE hdib;
-
- if (numFrames == 0)
- return;
-
- if (iFrame == 0) // Validate the first frame
- fPaint = FALSE;
-
- hdib = FrameRle(iFrame);
- hpal = FramePalette(iFrame);
-
- if (iFrame == 0)
- {
- SoundPlay(0, numFrames);
- nFramesPlayed = 0;
- msFrameBase = timeGetTime();
- }
-
- if (hpal)
- {
- hpalT = SelectPalette(hdc,hpal,FALSE);
- RealizePalette(hdc);
- }
-
- DibBlt(hdc,x,y,-1,-1,
- hdib,0,0,
- SRCCOPY,DIB_PAL_COLORS);
-
- if (hpal)
- SelectPalette(hdc,hpalT,FALSE);
- }
-
- //
- // Delete a given frame
- //
- BOOL DeleteFrame(int iFrame)
- {
- int i;
-
- if (iFrame < 0 || iFrame >= numFrames)
- return FALSE;
-
- if (iFrame < numFrames-1)
- {
- if (!RenderFrame(iFrame+1)) // Render the frame after it
- return FALSE;
-
- NukeRle(iFrame + 1);
-
- // if the next frame is using the same palette, make sure we
- // don't destroy the palette.
-
- if (!(arFrames[iFrame].f & F_PALSHARED) &&
- (arFrames[iFrame+1].f & F_PALSHARED))
- {
- arFrames[iFrame+1].f &= ~F_PALSHARED;
- arFrames[iFrame].f |= F_PALSHARED;
- }
-
- }
-
- FreeFrame(iFrame);
-
- for (i=iFrame; i<numFrames-1; i++)
- arFrames[i] = arFrames[i+1];
-
- numFrames--;
-
- if (iFrame == numFrames)
- iFrame--;
-
- fDirty = TRUE;
-
- ShowFrame(iFrame);
- return TRUE;
- }
-
- //
- // Insert a new frame before the given frame, iff iFrame is < 0 then
- // the frame will be appended
- // Normally we must render the frame after the one we insert, because if it's
- // a delta from its previous frame, that delta will be incorrect after another
- // frame is stuck in between them. Sometimes, if we know that problem won't
- // occur (eg. Convert Frames/Sec) we don't need to do this. That is the function
- // of the fRender flag.
- //
-
- BOOL InsertFrame(HANDLE hdib, int iFrame, BOOL fRender)
- {
- HANDLE hdibT;
- HPALETTE hpal, hpalT;
- BITMAPINFOHEADER bi;
- WORD f = 0;
- int i, j;
- BOOL fAppend;
-
- if (numFrames >= MAXFRAMES || hdib == NULL)
- return FALSE;
-
- fAppend = (iFrame < 0 || iFrame >= numFrames);
-
- DibInfo(hdib,&bi);
-
- //
- // we need a 8 bpp dib
- //
- if (bi.biCompression == BI_RGB && bi.biBitCount != 8)
- {
- hdibT = hdib;
-
- hdib = DibFromDib(hdib,BI_RGB,8,NULL,DIB_RGB_COLORS);
-
- if (hdib != hdibT)
- GFree(hdibT);
-
- if (!hdib)
- {
- ErrMsg("Out of Memory Error");
- return FALSE;
- }
- }
-
- // We must be given a DIB with RGB colours. Now switch it to
- // PAL colours.
-
- hpal = CreateDibPalette(hdib);
- SetPalFlags(hpal, 0,-1,wPalFlags);
- SetDibUsage(hdib,hpal,DIB_PAL_COLORS);
-
- //
- // alocate a slot for the frame.
- //
- if (fAppend)
- {
- iFrame = numFrames++;
- }
- else
- {
- if (fRender)
- {
- if (!RenderFrame(iFrame)) // Render the frame after this one
- return FALSE; // or we'll screw up the deltas
- NukeRle(iFrame);
- }
-
- for (i=numFrames; i>iFrame; i--)
- arFrames[i] = arFrames[i-1];
-
- numFrames++;
-
- // If frame i's palette is different from i+1, mark i+1 as UNshared, and
- // replace the run of palettes starting at i+1 with a new palette
-
- if (!PalEq(hpal,FramePalette(iFrame+1)) &&
- (FrameFlags(iFrame+1) & F_PALSHARED))
- {
- hpalT = CopyPalette(FramePalette(iFrame+1));
- arFrames[iFrame+1].f &= ~F_PALSHARED;
- arFrames[iFrame+1].hpal = hpalT;
- for (j=iFrame+2; j<numFrames && (FrameFlags(j) & F_PALSHARED); j++)
- arFrames[j].hpal = hpalT;
- }
-
- }
-
- //
- // If frame i's palette is the same as the one before it, mark frame i's
- // palette as shared, and erase it's copy.
- //
- if (iFrame > 0 && PalEq(hpal,FramePalette(iFrame-1)))
- {
- DeleteObject(hpal);
- hpal = FramePalette(iFrame-1);
- f |= F_PALSHARED;
- }
-
-
- if (bi.biCompression == BI_RGB)
- {
- arFrames[iFrame].hpal = hpal;
- arFrames[iFrame].f = f;
- arFrames[iFrame].hdib = hdib;
- arFrames[iFrame].hrle = NULL;
-
- }
- else // RLE DIB, just append it.
- {
- if (bi.biCompression == BI_RLE8)
- f |= F_RLE;
-
- arFrames[iFrame].hpal = hpal;
- arFrames[iFrame].f = f;
- arFrames[iFrame].hdib = NULL;
- arFrames[iFrame].hrle = hdib;
- }
-
- ShowFrame(iFrame);
- return TRUE;
- }
-
-
- void GetFramesSec(HWND hwnd)
- {
- if(fDialog(FRAMEDLG, hwnd, FrameDlgProc))
- fDirty=TRUE;
- }
-
- void GotoFrame(HWND hwnd)
- {
- RANGEDIALOGPARAM rdp;
-
- rdp.lpCaption = (LPSTR) "Goto Frame";
- rdp.min = 1;
- rdp.max = numFrames;
- rdp.current = curFrame + 1;
-
- ShowFrame(fDialogParam(DLG_RANGE,hwnd,
- fnRangeDlg,(DWORD) (LPRANGEDIALOGPARAM) &rdp) - 1);
- }
-
-
- void DeleteFrames(HWND hwnd)
- {
- RANGEDIALOGPARAM rdp;
- int iDelete;
- int saveCur = curFrame;
-
- rdp.lpCaption = (LPSTR) "# Frames to Delete:";
- rdp.min = 0;
- rdp.max = numFrames - curFrame;
- rdp.current = 0;
-
- iDelete = fDialogParam(DLG_RANGE,hwnd,
- fnRangeDlg,(DWORD) (LPRANGEDIALOGPARAM) &rdp);
-
- if (iDelete)
- {
- StartWait();
- while (iDelete-- > 0)
- {
- DeleteFrame(saveCur + iDelete);
- }
- EndWait();
- }
- }
-
- /*----------------------------------------------------------------------------*\
- | AppInit( hInst, hPrev) |
- | |
- | Description: |
- | This is called when the application is first loaded into |
- | memory. It performs all initialization that doesn't need to be done |
- | once per instance. |
- | |
- | Arguments: |
- | hInstance instance handle of current instance |
- | hPrev instance handle of previous instance |
- | |
- | Returns: |
- | TRUE if successful, FALSE if not |
- | |
- \*----------------------------------------------------------------------------*/
- BOOL AppInit(HANDLE hInst,HANDLE hPrev,WORD sw,LPSTR szCmdLine)
- {
- WNDCLASS cls;
- int dx,dy;
- HDC hdc;
- TEXTMETRIC tm;
- WORD w;
-
- arFrames = (FRAME far *)GAllocPtr((long)MAXFRAMES * sizeof(FRAME));
-
- if (!arFrames)
- return FALSE;
-
- arFrames[0].hdib = NULL;
- arFrames[0].hrle = NULL;
- arFrames[0].hpal = NULL;
- arFrames[0].f = NULL;
-
- w = SetErrorMode(0x8000);
- hDisplayDibDll = LoadLibrary(szDisplayDibDll);
- SetErrorMode(w);
-
- if (hDisplayDibDll > 32)
- DisplayDib = GetProcAddress(hDisplayDibDll, "DisplayDib");
- else
- hDisplayDibDll = NULL;
-
- /* Save instance handle for DialogBoxs */
- hInstApp = hInst;
-
- if (!hPrev)
- {
- /*
- * Register a class for the main application window
- */
- cls.hCursor = LoadCursor(NULL,IDC_ARROW);
- cls.hIcon = LoadIcon(hInst,"AppIcon");
- cls.lpszMenuName = "AppMenu";
- cls.lpszClassName = szAppName;
- cls.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE + 1;
- cls.hInstance = hInst;
- cls.style = CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
- cls.lpfnWndProc = (LPWNDPROC)AppWndProc;
- cls.cbWndExtra = 0;
- cls.cbClsExtra = 0;
-
- if (!RegisterClass(&cls))
- return FALSE;
- }
-
- hAccTable = LoadAccelerators(hInstApp, "AppAcc");
-
- hdc = GetDC(NULL);
- GetTextMetrics(hdc,&tm);
- tmHeight = tm.tmHeight;
- ReleaseDC(NULL,hdc);
-
- dx = GetSystemMetrics (SM_CXSCREEN);
- dy = GetSystemMetrics (SM_CYSCREEN);
-
- hwndApp = CreateWindow (szAppName, // Class name
- szAppName, // Caption
- WS_OVERLAPPEDWINDOW, // Style bits
- CW_USEDEFAULT, 0, // Position
- CW_USEDEFAULT, 0, // Size
- (HWND)NULL, // Parent window (no parent)
- (HMENU)NULL, // use class menu
- (HANDLE)hInst, // handle to window instance
- (LPSTR)NULL // no params to pass on
- );
- ShowWindow(hwndApp,sw);
- UpdateWindow(hwndApp);
-
- SetCursor(cls.hCursor);
- if (szCmdLine[0] != 0)
- PostMessage(hwndApp,WM_COMMAND,MENU_OPENRLE,(LONG)(LPSTR)szCmdLine);
- }
-
- /*----------------------------------------------------------------------------*\
- | WinMain( hInst, hPrev, lpszCmdLine, cmdShow ) |
- | |
- | Description: |
- | The main procedure for the App. After initializing, it just goes |
- | into a message-processing loop until it gets a WM_QUIT message |
- | (meaning the app was closed). |
- | |
- | Arguments: |
- | hInst instance handle of this instance of the app |
- | hPrev instance handle of previous instance, NULL if first |
- | szCmdLine ->null-terminated command line |
- | cmdShow specifies how the window is initially displayed |
- | |
- | Returns: |
- | The exit code as specified in the WM_QUIT message. |
- | |
- \*----------------------------------------------------------------------------*/
- int PASCAL WinMain(HANDLE hInst, HANDLE hPrev, LPSTR szCmdLine, WORD sw)
- {
- MSG msg;
- LONG msTime = 0L;
- int iFrame;
-
- if(GetWinFlags() & WF_CPU286)
- {
- ErrMsg("This program only works on an i386 or above.");
- return 0;
- }
-
- /* Call initialization procedure */
- if (!AppInit(hInst,hPrev,sw,szCmdLine))
- return FALSE;
-
- for (;;)
- {
- peek_again:
- while (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
- {
- if (msg.message == WM_QUIT)
- goto exit;
-
- if (!TranslateAccelerator(hwndApp, hAccTable, &msg))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
-
- // a typical do-something-as-fast-as-possible loop
- // note the all-important WaitMessage() call if nothing is
- // to be done. This gives up the CPU instead of hogging it.
-
- // app could/should also not do operation if it is not in the
- // foreground. (see WM_ACTIVATEAPP message)
- if (fPlay)
- {
-
- // example of how to do-something-exactly-so-often
-
- msTime = timeGetTime() - msFrameBase;
-
- iFrame = (int)(msTime * FramesSec / 1000 / FramesSecScale);
-
- if (iFrame <= curFrame)
- goto peek_again;
-
- if (fSkipFrames && iFrame > curFrame+1)
- {
- if (iFrame > numFrames)
- iFrame = numFrames;
-
- nFramesPlayed = iFrame-1;
- curFrame = iFrame-1;
- }
-
- nFramesPlayed++;
- ShowFrame(FRAME_NEXT);
- RealFramesSec = (long)nFramesPlayed*FramesSecScale*1000/msTime;
- }
- else
- WaitMessage();
- }
- exit:
- if (hDisplayDibDll)
- FreeLibrary(hDisplayDibDll);
-
- SoundClose();
-
- return msg.wParam;
- }
-
- void PaintStatus(HWND hwnd, HDC hdc)
- {
- RECT rc;
- char buf[128];
- char * pch;
- WORD f;
- long fps;
- BOOL fGetDC;
-
- if ((fStatus || fLoading) && numFrames > 0)
- {
- if (fGetDC = (hdc == NULL))
- hdc = GetDC(hwnd);
-
- GetClientRect(hwnd,&rc);
- rc.bottom = tmHeight;
-
- pch = buf;
-
- f = arFrames[curFrame].f;
-
- if (fPlay)
- {
- fps = RealFramesSec;
-
- pch += wsprintf(pch,"Frame: %d/%d fps=%d.%03d",
- curFrame+1, numFrames,
- (int)(fps/FramesSecScale),
- (int)(fps%FramesSecScale) );
- }
- else
- {
- pch += wsprintf(pch,"Frame: %d/%d Size=%ld",
- curFrame+1, (fLoading ? totFrames : numFrames),
- DIBSIZE(FrameRle(curFrame)));
-
- if (arFrames[curFrame].hdib)
- pch += wsprintf(pch," DIB");
-
- if (f & F_RLE)
- pch += wsprintf(pch," RLE");
- if (!(f & F_PALSHARED))
- pch += wsprintf(pch," PAL");
- if (f & F_KEYFRAME)
- pch += wsprintf(pch," KEY");
-
- fps = FramesSec;
-
- pch += wsprintf(pch, " fps=%d.%03d",
- (int)(fps/FramesSecScale),
- (int)(fps%FramesSecScale) );
- }
-
- ExtTextOut(hdc,0,0,ETO_OPAQUE,&rc,buf,lstrlen(buf),NULL);
- PatBlt(hdc,0,rc.bottom,rc.right,1,BLACKNESS);
-
- if (fGetDC)
- ReleaseDC(hwnd, hdc);
- }
- }
-
- /*----------------------------------------------------------------------------*\
- | AppPaint(hwnd, hdc) |
- | |
- | Description: |
- | The paint function. |
- | |
- | Arguments: |
- | hwnd window painting into |
- | hdc display context to paint to |
- | |
- | Returns: |
- | nothing |
- | |
- \*----------------------------------------------------------------------------*/
- void NEAR PASCAL AppPaint (HWND hwnd, HDC hdc)
- {
- RECT rc;
-
- PaintStatus(hwnd, hdc);
-
- if (!numFrames || fWait || fLoading || GetClipBox(hdc,&rc) == NULLREGION)
- return;
-
- if (fFullPaint)
- DrawDib(hdc, ptFrame.x, ptFrame.y, RenderFrame(curFrame), FramePalette(curFrame), DIB_PAL_COLORS);
- else
- PlayFrame(hdc, curFrame, ptFrame.x, ptFrame.y, FALSE);
- }
-
- /*----------------------------------------------------------------------------*\
- | AppWndProc( hwnd, uiMessage, wParam, lParam ) |
- | |
- | Description: |
- | The window proc for the app's main (tiled) window. This processes all |
- | of the parent window's messages. |
- | |
- | Arguments: |
- | hwnd window handle for the window |
- | uiMessage message number |
- | wParam message-dependent |
- | lParam message-dependent |
- | |
- | Returns: |
- | 0 if processed, nonzero if ignored |
- | |
- \*----------------------------------------------------------------------------*/
- LONG EXPORT AppWndProc(hwnd, msg, wParam, lParam)
- HWND hwnd;
- unsigned msg;
- WORD wParam;
- long lParam;
- {
- PAINTSTRUCT ps;
- BOOL f;
- HDC hdc;
- HPALETTE hpal,hpalT;
- RECT rc;
- BITMAPINFOHEADER bi;
-
- switch (msg)
- {
- case WM_CREATE:
- break;
-
- case WM_ERASEBKGND:
- break;
-
- case WM_NCHITTEST:
- if (fWait)
- {
- lParam = DefWindowProc(hwnd,msg,wParam,lParam);
-
- if (lParam == HTMENU)
- lParam = HTCLIENT;
-
- return lParam;
- }
- break;
-
- case WM_SETCURSOR:
- if (fWait && LOWORD(lParam) == HTCLIENT)
- {
- SetCursor(LoadCursor(NULL, IDC_WAIT));
- return TRUE;
- }
- break;
-
- case WM_SIZE:
- GetClientRect(hwnd, &rc);
-
- if (fStatus)
- rc.top += tmHeight+1;
-
- DibInfo(FrameRle(0),&bi);
-
- ptFrame.x = rc.left + (rc.right-rc.left-(int)bi.biWidth) / 2;
- ptFrame.y = rc.top + (rc.bottom-rc.top-(int)bi.biHeight) / 2;
-
- if (ptFrame.y < rc.top)
- ptFrame.y = rc.top;
-
- if (ptFrame.x < rc.left)
- ptFrame.x = rc.left;
-
- break;
-
- case WM_KEYDOWN:
- switch(wParam)
- {
- case VK_RIGHT: // next frame
- ShowFrame(FRAME_NEXT);
- break;
-
- case VK_LEFT: // previous frame
- ShowFrame(FRAME_PREV);
- break;
-
- case VK_HOME:
- ShowFrame(0);
- break;
-
- case VK_END:
- ShowFrame(numFrames-1);
- break;
-
- case VK_NEXT:
- if (numFrames)
- {
- curFrame += 10;
- if (curFrame > numFrames - 1)
- curFrame = numFrames - 1;
- }
- ShowFrame(curFrame);
- break;
-
- case VK_PRIOR:
- if (numFrames)
- {
- curFrame -= 10;
- if (curFrame < 0)
- curFrame = 0;
- }
- ShowFrame(curFrame);
- break;
- }
-
- break;
-
- case WM_ACTIVATEAPP:
- fActive = wParam;
- break;
-
- case WM_TIMER:
- if (!fWait)
- ShowFrame(FRAME_NEXT);
- break;
-
- case WM_INITMENU:
- f = (IsClipboardFormatAvailable(CF_DIB)||
- IsClipboardFormatAvailable(CF_BITMAP))
- ? MF_ENABLED : MF_GRAYED;
-
- EnableMenuItem (wParam,MENU_PASTE_APPEND ,f);
- EnableMenuItem (wParam,MENU_PASTE_INSERT ,f);
- EnableMenuItem (wParam,MENU_PASTE_REPLACE,f);
-
- f = IsClipboardFormatAvailable(CF_PALETTE) ? MF_ENABLED : MF_GRAYED;
-
- EnableMenuItem (wParam,MENU_PASTE_PALETTE ,f);
- EnableMenuItem (wParam,MENU_REVERT, gszCurFilespec[0] != '\0'
- ? MF_ENABLED : MF_GRAYED);
-
- f = (numFrames > 0 ) ? MF_ENABLED : MF_GRAYED;
-
- EnableMenuItem(wParam, MENU_SAVE_RLE, f);
- EnableMenuItem(wParam, MENU_SAVE_RL0, f);
- EnableMenuItem(wParam, MENU_SAVE_FRAMES, f);
- EnableMenuItem(wParam, MENU_COPY, f);
- EnableMenuItem(wParam, MENU_CUT, f);
- EnableMenuItem(wParam, MENU_DELETE_FRAME,f);
- EnableMenuItem(wParam, MENU_DELETE_FRAMES,f);
- EnableMenuItem(wParam, MENU_GOTO_FRAME,f);
- EnableMenuItem(wParam, MENU_RLEFRAMES,f);
- EnableMenuItem(wParam, MENU_IDENTITY,f);
-
- f = (pWaveFormat && pwhMovie) ? MF_ENABLED : MF_GRAYED;
- EnableMenuItem (wParam,MENU_SAVE_WAVE, f);
-
- CheckMenuItem(wParam,MENU_WINDOW, gDisplayMode ? MF_UNCHECKED : MF_CHECKED);
-
- if (hDisplayDibDll)
- {
- CheckMenuItem(wParam,MENU_320x240,
- gDisplayMode == DISPLAYDIB_MODE_320x240x8
- ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(wParam,MENU_320x200,
- gDisplayMode == DISPLAYDIB_MODE_320x200x8
- ? MF_CHECKED : MF_UNCHECKED);
- } else
- {
- EnableMenuItem(wParam,MENU_320x240, MF_GRAYED);
- EnableMenuItem(wParam,MENU_320x200, MF_GRAYED);
- }
-
- CheckMenuItem (wParam,MENU_STATUS, fStatus ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem (wParam,MENU_FULLPAINT, fFullPaint ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem (wParam,MENU_SKIPFRAMES, fSkipFrames ? MF_CHECKED : MF_UNCHECKED);
-
- break;
-
- case WM_COMMAND:
- return AppCommand(hwnd,msg,wParam,lParam);
-
- case WM_DESTROY:
- FreeFrames();
- PostQuitMessage(0);
- break;
-
- case WM_QUERYENDSESSION:
- if (!QueryClose(hwnd))
- return 0L;
- break;
-
- case WM_CLOSE:
- if (fWait || !QueryClose(hwnd))
- return 0L;
- break;
-
- case WM_LBUTTONDBLCLK:
- PostMessage(hwnd,WM_COMMAND,MENU_PLAY,0L);
- break;
-
- case WM_PALETTECHANGED:
- if (wParam == hwnd)
- break;
-
- // fall through
-
- case WM_QUERYNEWPALETTE:
- /* if palette realization causes a palette change,
- ** we need to do a full redraw.
- */
-
- if ((numFrames) && (hpal = FramePalette(curFrame)))
- {
- hdc = GetDC(hwnd);
- hpalT = SelectPalette (hdc, hpal, FALSE);
-
- f = RealizePalette(hdc);
-
- SelectPalette (hdc, hpalT, FALSE);
- ReleaseDC(hwnd, hdc);
-
- if (f)
- InvalidateRect(hwnd, NULL, TRUE);
-
- return (LONG)f;
- }
- return 0L;
-
- case WM_PAINT:
- BeginPaint(hwnd,&ps);
- fPaint = TRUE;
- AppPaint (hwnd,ps.hdc);
- EndPaint(hwnd,&ps);
- return 0L;
- }
- return DefWindowProc(hwnd,msg,wParam,lParam);
- }
-
- LONG NEAR PASCAL AppCommand (hwnd, msg, wParam, lParam)
- HWND hwnd;
- unsigned msg;
- WORD wParam;
- long lParam;
- {
- char szFile[128];
- char ach[128];
- HANDLE hdib;
- HBITMAP hbm;
- HPALETTE hpal;
- int iFrame;
- LPSTR pch;
-
- switch(wParam)
- {
- case MENU_ABOUT:
- fDialog(ABOUTBOX,hwnd,AppAbout);
- break;
-
- case MENU_EXIT:
- PostMessage(hwnd,WM_CLOSE,0,0L);
- break;
-
- case MENU_FRAMES_SEC:
- GetFramesSec(hwnd);
- PaintStatus(hwnd, NULL);
- break;
-
- case MENU_SKIPFRAMES:
- fSkipFrames = !fSkipFrames;
- break;
-
- case MENU_RLEFRAMES:
- RleAllFrames(hwnd);
- break;
-
- case MENU_NEXT:
- ShowFrame(FRAME_NEXT);
- break;
-
- case MENU_PREV:
- ShowFrame(FRAME_PREV);
- break;
-
- case MENU_WINDOW:
- gDisplayMode = 0;
- break;
-
- case MENU_320x240:
- gDisplayMode = DISPLAYDIB_MODE_320x240x8;
- break;
-
- case MENU_320x200:
- gDisplayMode = DISPLAYDIB_MODE_320x200x8;
- break;
-
- case MENU_NEW:
- if (!QueryClose(hwnd))
- break;
-
- StartWait();
- gszCurFilespec[0] = '\0';
- SetWindowText(hwnd, szAppName);
- FreeFrames();
- InvalidateRect(hwnd,NULL,TRUE);
- UpdateWindow(hwnd);
- EndWait();
- break;
-
- case MENU_PLAY:
- if (gDisplayMode)
- {
- PlayVga(hwnd);
- return 0L;
- }
-
- if (fPlay = !fPlay)
- {
- SoundOpen();
-
- // movie starts NOW
- msFrameBase = timeGetTime()-curFrame*FramesSecScale*1000/FramesSec;
- nFramesPlayed = curFrame;
-
- SoundPlay(curFrame, numFrames - curFrame);
- }
- else
- {
- SoundClose();
- PaintStatus(hwnd, NULL);
- }
- break;
-
- case MENU_STATUS:
- fStatus = !fStatus;
- SendMessage(hwnd,WM_SIZE,0,0L);
- InvalidateRect(hwnd,NULL,TRUE);
- break;
-
- case MENU_FULLPAINT:
- fFullPaint = !fFullPaint;
- InvalidateRect(hwnd, NULL, FALSE);
- break;
-
- case MENU_PURGE:
- PurgeFrames();
- break;
-
- case MENU_DELETE_FRAME:
- DeleteFrame(curFrame);
- break;
-
- case MENU_DELETE_FRAMES:
- DeleteFrames(hwnd);
- break;
-
- case MENU_GOTO_FRAME:
- GotoFrame(hwnd);
- break;
-
- case MENU_PASTE_REPLACE:
- iFrame = curFrame;
- DeleteFrame(curFrame);
- goto do_insert;
-
- case MENU_PASTE_APPEND:
- iFrame = -1;
- goto do_insert;
-
- case MENU_PASTE_INSERT:
- iFrame = curFrame;
-
- do_insert:
- if (OpenClipboard(hwnd))
- {
- if (hdib = GetClipboardData(CF_DIB))
- {
- hdib = GSelector(hdib);
- InsertFrame(CopyDib(hdib), iFrame, TRUE);
- }
- else if (hbm = GetClipboardData(CF_BITMAP))
- {
- hpal = GetClipboardData(CF_PALETTE);
-
- if (!hpal)
- hpal = GetStockObject(DEFAULT_PALETTE);
-
- hdib = DibFromBitmap(hbm,BI_RGB,8,hpal,DIB_RGB_COLORS);
-
- InsertFrame(hdib, iFrame, TRUE);
- }
- CloseClipboard();
- }
- break;
-
- case MENU_COPY:
- case MENU_CUT:
- if (OpenClipboard(hwnd))
- {
- StartWait();
- EmptyClipboard();
- if (hdib = CopyDib(RenderFrame(curFrame)))
- {
- hpal = CopyPalette(FramePalette(curFrame));
- hbm = BitmapFromDib(hdib, hpal, DIB_PAL_COLORS);
-
- SetDibUsage(hdib,hpal,DIB_RGB_COLORS);
- SetClipboardData(CF_DIB,hdib);
- SetClipboardData(CF_PALETTE,hpal);
- SetClipboardData(CF_BITMAP,hbm);
- }
- CloseClipboard();
-
- if (wParam == MENU_CUT)
- DeleteFrame(curFrame);
-
- EndWait();
- }
- break;
-
- case MENU_REVERT:
- lstrcpy(szFile,(LPSTR)gszCurFilespec);
- goto open_it;
-
- case MENU_OPENRLE:
- lstrcpy(szFile,(LPSTR)lParam);
- goto open_it;
-
- case MENU_OPEN:
- case MENU_LOAD_APPEND:
- case MENU_LOAD_INSERT:
-
- szFile[0] = 0;
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = hwnd;
- ofn.hInstance = hInstApp;
- ofn.lpstrFilter = szFilters;
- ofn.nFilterIndex = 1;
- ofn.lpstrCustomFilter = NULL;
- ofn.nMaxCustFilter = 0;
- ofn.lpstrFile = szFile;
- ofn.nMaxFile = sizeof(szFile);
- ofn.lpstrFileTitle = NULL;
- ofn.nMaxFileTitle = 0;
- ofn.lpstrInitialDir = NULL;
- ofn.lpstrTitle = "Open File";
- ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
- ofn.lCustData = 0;
- ofn.nFileOffset = 0;
- ofn.nFileExtension = 0;
- ofn.lpstrDefExt = NULL;
- ofn.lpfnHook = NULL;
- ofn.lpTemplateName = NULL;
-
- if (!GetOpenFileName(&ofn))
- return 0L;
- open_it:
- if (fPlay) // Stop the movie!
- SendMessage(hwnd,WM_COMMAND,MENU_PLAY,0L);
- switch (wParam)
- {
- case MENU_REVERT:
-
- if (fDirty)
- {
- if (MessageBox(hwnd,"Revert to last copy saved?",
- szAppName,MB_OKCANCEL|MB_ICONQUESTION|MB_TASKMODAL)
- == IDCANCEL)
- break;
- fDirty = FALSE;
- }
-
- case MENU_OPENRLE:
- case MENU_OPEN:
- if (OpenWavFile(szFile)) // See if its a wave file
- break; // and don't call FILE_NEW
- SendMessage(hwnd,WM_COMMAND,MENU_NEW,0L);
- SetWindowText(hwnd, szAppName);
- if (OpenMovieFile(szFile, -1)) // remember filespec for revert
- { // and update window title
- wsprintf(ach, "%ls - %ls", (LPSTR)szAppName, (LPSTR)szFile);
- SetWindowText(hwnd, ach);
- lstrcpy(gszCurFilespec, szFile);
- }
- SendMessage(hwnd,WM_SIZE,0,0L);
- ShowFrame(0);
- break;
-
- case MENU_LOAD_APPEND:
- OpenMovieFile(szFile, -1);
- fDirty = TRUE;
- InvalidateRect(hwnd,NULL,TRUE);
- break;
-
- case MENU_LOAD_INSERT:
- OpenMovieFile(szFile, curFrame);
- fDirty = TRUE;
- InvalidateRect(hwnd,NULL,TRUE);
- break;
- }
- break;
-
- case MENU_SAVE_RL0:
- case MENU_SAVE_WAVE:
- case MENU_SAVE_RLE:
- if (fPlay) // STOP THE MOVIE!!!
- SendMessage(hwnd,WM_COMMAND,MENU_PLAY,0L);
-
- switch(wParam)
- {
- case MENU_SAVE_RLE: pch = "*.rle"; break;
- case MENU_SAVE_RL0: pch = "*.rl0"; break;
- case MENU_SAVE_WAVE: pch = "*.wav"; break;
- }
-
- szFile[0] = 0;
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = hwnd;
- ofn.hInstance = hInstApp;
- ofn.lpstrFilter = szFilters;
- ofn.nFilterIndex = 1;
- ofn.lpstrCustomFilter = NULL;
- ofn.nMaxCustFilter = 0;
- ofn.lpstrFile = szFile;
- ofn.nMaxFile = sizeof(szFile);
- ofn.lpstrFileTitle = NULL;
- ofn.nMaxFileTitle = 0;
- ofn.lpstrInitialDir = NULL;
- ofn.lpstrTitle = "Save File";
- ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
- ofn.lCustData = 0;
- ofn.nFileOffset = 0;
- ofn.nFileExtension = 0;
- ofn.lpstrDefExt = NULL;
- ofn.lpfnHook = NULL;
- ofn.lpTemplateName = NULL;
-
- if (!GetSaveFileName(&ofn))
- break;
-
- switch(wParam)
- {
- case MENU_SAVE_RLE:
- SaveRleFile(szFile,0,numFrames);
- break;
-
- case MENU_SAVE_RL0:
- SaveRl0File(szFile,0,numFrames);
- AnsiLower(szFile);
- wsprintf(ach, "%ls - %ls",
- (LPSTR)szAppName, (LPSTR)szFile);
- SetWindowText(hwnd, ach);
- lstrcpy(gszCurFilespec, szFile);
- break;
-
- case MENU_SAVE_WAVE:
- SaveWavFile(szFile,0,numFrames);
- break;
- }
-
- fDirty = FALSE;
- break;
-
- case MENU_REDRAW:
- InvalidateRect(hwnd,NULL,TRUE);
- break;
-
- case MENU_REALIZE:
- RealizeFrames();
- break;
-
- case MENU_IDENTITY:
- MapIdentFrames();
- break;
-
- case MENU_PASTE_PALETTE:
- if (OpenClipboard(hwnd))
- {
- PurgeFrames(); // if a frame has both a hdib & hrle, this
- // could screw up when we RLE the movie
- hpal = GetClipboardData(CF_PALETTE);
- CloseClipboard();
-
- MapPalFrames(CopyPalette(hpal));
- }
- break;
- }
- return 0L;
- }
-
- /*----------------------------------------------------------------------------*\
- | QueryClose - Ask user to save
- \*----------------------------------------------------------------------------*/
- BOOL QueryClose(HWND hwnd)
- {
- int i;
-
- if (fDirty)
- {
- i = MessageBox(hwnd,"RLE file has changed.\nSave changes?",
- szAppName,MB_YESNOCANCEL|MB_ICONQUESTION|MB_TASKMODAL);
-
- switch(i)
- {
- case IDYES:
- SendMessage(hwnd, WM_COMMAND, MENU_SAVE_RL0, 0L);
- return TRUE;
- case IDNO:
- return TRUE;
- default:
- case IDCANCEL:
- return FALSE;
- }
- }
- return TRUE;
- }
-
- /*
- * CopyPalette, makes a copy of a GDI logical palette
- */
- HPALETTE CopyPalette(HPALETTE hpal)
- {
- PLOGPALETTE ppal;
- int nNumEntries;
-
- if (!hpal)
- return NULL;
-
- GetObject(hpal,sizeof(int),(LPSTR)&nNumEntries);
-
- if (nNumEntries == 0)
- return NULL;
-
- ppal = (PLOGPALETTE)LocalAlloc(LPTR,sizeof(LOGPALETTE) +
- nNumEntries * sizeof(PALETTEENTRY));
-
- if (!ppal)
- return NULL;
-
- ppal->palVersion = PALVERSION;
- ppal->palNumEntries = nNumEntries;
-
- GetPaletteEntries(hpal,0,nNumEntries,ppal->palPalEntry);
-
- hpal = CreatePalette(ppal);
-
- LocalFree((HANDLE)ppal);
- return hpal;
- }
-